import axios from 'axios'
import { getToken } from '../utils/auth.js'
import { log, error } from '../utils/log.js'
import db from '../utils/localstorage.js'

let router = null
const baseURL = `/api/`

// 请求超时时间，10s
const requestTimeOut = 30 * 1000
const success = 200

// 系统令牌刷新请求对象
const refresh_service = axios.create({
  baseURL,
  timeout: requestTimeOut,
  responseType: 'json',
  validateStatus(status) {
    return status === success
  }
})

refresh_service.interceptors.request.use(
  config => {
    const _config = config
    try {
      // _config.headers['timestamp'] = new Date().getTime()
      // _config.headers['key-sign'] = md5(appKey + new Date().getTime())
    } catch (e) {
      error(e)
    }
    return _config
  },
  error => {
    log(error)
    return Promise.reject(error)
  }
)

// response interceptor
refresh_service.interceptors.response.use(
  (config) => {
    return config
  }, 
  (error) => {
    return error.response || error
  }
)

// 系统全局请求对象
// 鉴于运营后台生产环境受攻击，急需进行运营后台网关安全升级：
// 1，升级springCloudGateway版本，防止远程代码执行安全漏洞
// 2，请求头增加两字段，key-sign签名数据，timestamp当前时间戳

// 后端分配给前端appKey=dKVJl5kS44tNtXw 该appKey表示授权的客户端
// 签名算法：key-sign=md5(appKey+timestamp)
export const service = axios.create({
  baseURL,
  timeout: requestTimeOut,
  headers: {
    'Content-Type': 'application/json'
  },
  responseType: 'json',
  validateStatus(status) {
    return status === success
  }
})

service.interceptors.request.use(
  config => {
    let _config = config
    try {
      const token = getToken()
      if (config.noAuthorizationHeader) {
        delete _config.headers['Authorization']
      } else {
        _config.headers['Authorization'] = `Bearer ${token}`
      }
    } catch (e) {
      error(e)
    }
    return _config
  },
  error => {
    log(error)
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  (config) => {
    return config
  },
  (error) => {
    log('Response error', error)
    if (error.response) {
      const errorMessage = error.response.data === null ? '系统内部异常，请联系网站管理员' : error.response.data.message
      switch (error.response.status) {
        case 404:
          log('Not found')
          break
        case 403:
          log('No Permissions')
          break
        case 401:
          // db.remove('ACCESS_TOKEN')
          // window.location.href = '/login'
          break
        default:
          if (errorMessage === 'refresh token invalide') {
            log('Login Expire')
          } else {
            log(errorMessage)
          }
          break
      }
    }
    return Promise.reject(error)
  }
)

export const request = {
  login(url, params = {}) {
    return refresh_service.get(url, params, {
      transformRequest: [(params) => {
        return tansParams(params)
      }],
      headers: {
        // 'Authorization': authorizationValue,
        // 'Content-Type': 'application/x-www-form-urlencoded'
      },
      // loginRequest: true
    })
  },
  post(url, params = {}) {
    return service.post(url, params, {
      transformRequest: [(params) => {
        return JSON.stringify(params)
      }],
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      }
    })
  },
  put(url, params = {}) {
    return service.put(url, params, {
      transformRequest: [(params) => {
        return tansParams(params)
      }],
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
  },
  get(url, params = {}) {
    let _params
    if (Object.is(params, undefined)) {
      _params = ''
    } else {
      _params = '?'
      for (const key in params) {
        // eslint-disable-next-line no-prototype-builtins
        if (params.hasOwnProperty(key) && params[key] !== null) {
          _params += `${key}=${params[key]}&`
        }
      }
    }
    return service.get(`${url}${_params}`)
  },
  delete(url, params = {}) {
    let _params
    if (Object.is(params, undefined)) {
      _params = ''
    } else {
      _params = '?'
      for (const key in params) {
        // eslint-disable-next-line no-prototype-builtins
        if (params.hasOwnProperty(key) && params[key] !== null) {
          _params += `${key}=${params[key]}&`
        }
      }
    }
    return service.delete(`${url}${_params}`)
  }
}

function tansParams(params) {
  let result = ''
  Object.keys(params).forEach((key) => {
    if (!Object.is(params[key], undefined) && !Object.is(params[key], null)) {
      result += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + '&'
    }
  })
  return result
}

export const useAxios = (app, appRouter) => {
  app.provide('$axios', service)
  app.provide('$request', request)
  router = appRouter
}
